#include "byteitemdelegate.h"

#include <assert.h>
#include <QPainter>
#include <QStyleOption>
#include <QStyleOptionViewItemV4>


ByteItemDelegate::ByteItemDelegate(QObject *parent)
	: QStyledItemDelegate(parent)
	, _vm(vmDecimal)
{

}

ByteItemDelegate::~ByteItemDelegate()
{

}

template<class T>
QString toBitString(T c)
{
	QString str;
	for (unsigned int i = 0; i < sizeof(T) * 8; ++i)
	{
		str += ((c >> i) & 1) ? "1" : "0";
	}
	return str;
}


void ByteItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
	if (_vm == vmBitPixel)
	{
		painter->save();
		//painter->setClipRect(option.rect);
		painter->fillRect(option.rect, (option.state & QStyle::State_Selected) ? option.palette.color(QPalette::Highlight)/* Qt::blue*/ : Qt::black);
		painter->setPen((option.state & QStyle::State_Selected) ? option.palette.color(QPalette::HighlightedText) : Qt::green);
		unsigned char b = index.data().toInt();
                for (unsigned int i = 0; i < sizeof(b)*8; ++i)
		{
			if ((b >> i) & 1) painter->drawPoint(option.rect.x() + i, option.rect.y() + option.rect.height()/2);
		}
		painter->restore();
		return;
	}
	else //if (_vm == vmSymbol)
	{
		painter->save();
		if (const QStyleOptionViewItemV4 *v4 = qstyleoption_cast<const QStyleOptionViewItemV4 *>(&option)) {
			QPalette::ColorGroup cg = v4->state & QStyle::State_Enabled
				? QPalette::Normal : QPalette::Disabled;
			if (cg == QPalette::Normal && !(v4->state & QStyle::State_Active))
				cg = QPalette::Inactive;

			//if (v4->showDecorationSelected && (v4->state & QStyle::State_Selected)) {
			//	painter->fillRect(v4->rect, v4->palette.brush(cg, QPalette::Highlight));
			//} else {
			//	if (v4->backgroundBrush.style() != Qt::NoBrush) {
			//		QPointF oldBO = painter->brushOrigin();
			//		painter->setBrushOrigin(v4->rect.topLeft());
			//		painter->fillRect(v4->rect, v4->backgroundBrush);
			//		painter->setBrushOrigin(oldBO);
			//	}
			//}

			if (v4->state & QStyle::State_Selected) {
				//QRect textRect = subElementRect(QStyle::SE_ItemViewItemText,  opt, widget);
				painter->fillRect(v4->rect, v4->palette.brush(cg, QPalette::Highlight));
			}

			if (v4->state & QStyle::State_Selected) {
				painter->setPen(v4->palette.color(cg, QPalette::HighlightedText));
			} else {
				painter->setPen(v4->palette.color(cg, QPalette::Text));
			}

			painter->drawText(option.rect, Qt::AlignCenter, displayText(index.data(), v4->locale));

			//if (option.state & QStyle::State_Selected) painter->fillRect(option.rect, Qt::blue);
		}
		painter->restore();
		return;
	}
	return QStyledItemDelegate::paint(painter, option, index);
}

QString ByteItemDelegate::displayText( const QVariant &value, const QLocale &locale ) const
{
//	assert(value.type() == QVariant::Char );

	unsigned char b = value.toInt();
	switch (_vm)
	{
	case vmDecimal: return QString::number((int)b);
	case vmHEX: return QString("%1").arg((uint)b, 2, 16, QChar('0')).toUpper();
	case vmBinary: return toBitString(b); 
	case vmBinaryInverted: return QString("%1").arg((uint)b, 8, 2, QLatin1Char('0')).toUpper();//toBitString(b); 
	case vmSymbol: return QChar(b);
	}
	return QStyledItemDelegate::displayText(value, locale);
}

ViewMode ByteItemDelegate::getViewMode() const
{
	return _vm;
}

void ByteItemDelegate::setViewMode( ViewMode vm )
{
	_vm = vm;
}
